package birdsong.tests;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;

import java.io.IOException;
import java.net.UnknownHostException;

import org.junit.Before;
import org.junit.Test;

import FollowME.ServerToClientMessage;
import birdsong.comm.ClientSideMessage;
import birdsong.comm.ServerSideMessage.Type;
import birdsong.dummy.ClientCommDummy;
import birdsong.dummy.ServerCommDummy;

public class ServerCommDummyTest {

	private ClientCommDummy clientA;
	private ClientCommDummy clientB;

	private ServerCommDummy server;

	private static final String A = "A";
	private static final String B = "B";
	private static final String localhost = "localhost";
	private ServerToClientMessage messageFromServer;
	private ClientCommDummy clientX;

	@Before
	public void setUp() throws Exception {

		server = new ServerCommDummy();
		server.start();

		clientA = new ClientCommDummy();
		clientB = new ClientCommDummy();

		clientA.connect(localhost, A);
		clientB.connect(localhost, B);
		clientX = new ClientCommDummy();
	}

	@Test
	public void testGetNextMessage() {

		assertNull(server.getNextMessage());
		clientA.sendBirdsongMessage("message");
		assertNotNull(server.getNextMessage());

	}

	@Test
	public void testHasNextMessage() throws InterruptedException {

		assertFalse(server.hasNextMessage());
		clientA.sendBirdsongMessage("message");
		assertTrue(server.hasNextMessage());

	}

	@Test
	public void testSendBirdsongMessage() {

		server.sendBirdsongMessage(A, B, "birdsongMessage");
		messageFromServer = (ServerToClientMessage) clientB.getNextMessage();
		assertNotNull(messageFromServer);
		assertEquals("birdsongMessage", messageFromServer.getPayload());

	}

	@Test
	public void testSendNewFollower() {

		clientA.follow(B);
		messageFromServer = (ServerToClientMessage) clientB.getNextMessage();
		assertNotNull(messageFromServer);
		assertEquals(Type.FOLLOW, messageFromServer.getType());

	}

	@Test
	public void testSendNewUnfollow() {

		clientA.unfollow(B);
		messageFromServer = (ServerToClientMessage) clientB.getNextMessage();
		assertNotNull(messageFromServer);
		assertEquals(Type.UNFOLLOW, messageFromServer.getType());

	}

	@Test
	public void testSendError() {
		clientA.follow("C");
		messageFromServer = (ServerToClientMessage) clientA.getNextMessage();
		assertNotNull(messageFromServer);
		assertEquals(ClientSideMessage.Type.ERROR, messageFromServer.getType());
	}

	@Test
	public void testSendClientConnected() throws UnknownHostException,
			IOException {
		clientX.connect(localhost, "X");
		messageFromServer = (ServerToClientMessage) clientX.getNextMessage();
		assertNotNull(messageFromServer);
		assertEquals(ClientSideMessage.Type.CONNECTED,
				messageFromServer.getType());
	}

	@Test
	public void testSendClientDisconnected() {
		clientX.disconnect();
		messageFromServer = (ServerToClientMessage) clientX.getNextMessage();
		assertNotNull(messageFromServer);
		assertEquals(ClientSideMessage.Type.DISCONNECTED,
				messageFromServer.getType());
	}

}
